package com.shp.service.serviceImpl;

import com.shp.dao.*;
import com.shp.pojo.*;
import com.shp.service.GoodsService;
import com.shp.utils.DateUtil;
import com.shp.utils.StringUtil;
import com.shp.utils.UploadUtil;
import com.shp.utils.UuidUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * @author zwl
 * @Version: 1.0
 * @create: 2020/2/24 18:39
 */
@Service("goodsService")
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private ImageDao imageDao;

    @Autowired
    private GoodsDao goodsDao;

    @Autowired
    private CatelogDao catelogDao;

    @Autowired
    private SelectedDao selectedDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private CommentsDao commentsDao;

    /**
     * 保存图片数据到磁盘
     *
     * @param filesMap 图片数据Map
     * @return true代表保存成功；否则代表包村失败
     */
    @Override
    public boolean saveImagesToDisk(Map<String, MultipartFile> filesMap) {
        // 保存图片文件的磁盘目录
        String imagesAddress = UploadUtil.getImagesAddress();
        // 图片文件
        MultipartFile file = null;
        for (String fileName : filesMap.keySet()) {
            // 图片对象
            File newFile = new File(imagesAddress + "/" + fileName);
            //获取图片文件
            file = filesMap.get(fileName);
            try {
                // 将内存中的数据写入到磁盘
                file.transferTo(newFile);
            } catch (IOException e) {
                e.printStackTrace();
                // 写入出错，退出
                return false;
            }
        }
        // 文件保存成功
        return true;
    }

    /**
     * 获取网站主页需要的所有商品信息
     *
     * @param model org.springframework.ui
     * @return Model
     */
    @Override
    public void setGoodsMsgOnIndex(Model model) {

        List<Good> goodsList = null;
        List<Image> imageList = null;
        List<GoodsExtend> goodsAndImagesList = new ArrayList<GoodsExtend>();

        /*
        获取后台推荐的商品列表,数量不限
         */
        goodsList = selectedDao.getSelectedGoods();
        for(Good goods : goodsList){
            // 将goods信息和对应的images信息封装进GoodsExtend对象中,再将GoodsExtend对象保存到goodsAndImagesList中，传递给前台
            GoodsExtend goodsExtend = new GoodsExtend();
            imageList = imageDao.getImagesByGoodsId(goods.getId());
            // 对商品描述进行省略处理
            goods.setDescrible(StringUtil.setHidden(goods.getDescrible(),24,"..."));
            goodsExtend.setGoods(goods);
            goodsExtend.setImageList(imageList);
            goodsAndImagesList.add(goodsExtend);
        }
        model.addAttribute("selectedGoodsList",goodsAndImagesList);

        /*
        获取各种类型的商品列表（最新发布的），商品种类数量7，每种类型的商品数量6
         */
        // 商品种类数量
        int catelogSize = 7;
        // 每种类型的商品数量
        int goodsSize = 6;
        for(int i = 1;i <= catelogSize;i++){
            goodsList = goodsDao.getGoodsByCatelogAndDate(i, goodsSize);
            goodsAndImagesList = new ArrayList<GoodsExtend>();
            for(Good goods : goodsList){
                // 将goods信息和对应的images信息封装进GoodsExtend对象中,再将GoodsExtend对象保存到goodsAndImagesList中，传递给前台
                GoodsExtend goodsExtend = new GoodsExtend();
                imageList = imageDao.getImagesByGoodsId(goods.getId());
                // 对商品描述进行省略处理
                goods.setDescrible(StringUtil.setHidden(goods.getDescrible(),24,"..."));
                goodsExtend.setGoods(goods);
                goodsExtend.setImageList(imageList);
                goodsAndImagesList.add(goodsExtend);
            }
            model.addAttribute("catelogList" + i, goodsAndImagesList);
        }
    }

    /**
     * 获取商品的详细信息
     *
     * @param model org.springframework.ui
     * @param id  商品id
     */
    @Override
    public void setGoodsDetail(Model model, Integer id) {
        // 获取商品
        Good goods = goodsDao.getGoodsById(id);
        // 获取商品图片列表
        List<Image> imageList = imageDao.getImagesByGoodsId(goods.getId());
        // 获取商品评论列表
        List<Comments> commentsList = commentsDao.getCommentsListByGoodsId(goods.getId());
        // 获取卖出者
        User seller = userDao.getUserById(goods.getUser_id());
        // 获取分类
        Catelog catelog = catelogDao.getCatelogById(goods.getCatelog_id());

        /*
        将商品信息,分类和卖出者，保存到GoodsExtend,再传递到前台
         */
        GoodsExtend goodsExtend = new GoodsExtend();
        goodsExtend.setGoods(goods);
        goodsExtend.setImageList(imageList);
        goodsExtend.setCommentsList(commentsList);

        model.addAttribute("goodsExtend",goodsExtend);
        model.addAttribute("catelog",catelog);
        model.addAttribute("seller",seller);
    }

    /**
     * 添加评论信息到数据库
     *
     * @param info     响应对象ResultInfo
     * @param comments 上传的评论信息
     * @param request  HttpServletRequest
     * @return 响应对象ResultInfo
     */
    @Override
    public ResultInfo addComments(ResultInfo info, Comments comments, HttpServletRequest request) {
        // 获取评论用户
        User activeUser = (User)request.getSession().getAttribute("activeUser");
        // 设置 评论发布时间
        comments.setCreate_at(DateUtil.getNowTime());
        // 设置   Comments的user_id
        comments.setUser_id(activeUser.getId());
        // 将评论保存到数据库
        int row = commentsDao.insert(comments);
        if(row > 0){
            info.setFlag(true);
            comments.setUserName(activeUser.getUserName());
            info.setDatas(comments);
        }else{
            info.setErrorMsg("评论失败");
        }
        return info;
    }

    /**
     * 根据发布日期，查询精选商品
     *
     * @param size 商品数量
     * @return List<GoodsExtend>
     */
    @Override
    public List<GoodsExtend> getSelectedGoodsByDate(int size) {
        return selectedDao.getSelectedGoodsByDate(size);
    }

    /**
     * 根据商品的分类id，查询指定数量的商品
     *
     * @param id   分类id
     * @param size 商品个数
     * @return List<GoodsExtend>
     */
    @Override
    public List<GoodsExtend> getCategoryGoodsByIdAndDate(Integer id, Integer size) {
        return goodsDao.getCategoryGoodsByIdAndDate(id,size);
    }

    /**
     * 根据商品分类id，查询该分类的所有商品,按照发布日期降序
     * 配合使用分页插件pageHelper，进行分页处理
     *
     * @param categoryId 分类id
     * @return List<GoodsExtend>
     */
    @Override
    public List<GoodsExtend> getCategoryGoodsList(Integer categoryId) {
        return goodsDao.getCategoryGoods(categoryId);
    }

    /**
     * 查询所有的推荐的商品
     * 配合使用分页插件pageHelper，进行分页处理
     *
     * @return List<GoodsExtend>
     */
    @Override
    public List<GoodsExtend> getSelectedGoodsList() {
        return goodsDao.getSelectedGoods();
    }

    /**
     * 根据商品名称或描述，模糊查询商品
     *
     * @param name     商品名称
     * @param describe 商品描述
     * @return List<GoodsExtend>
     */
    @Override
    public List<GoodsExtend> searchGoodsList(String name, String describe) {
        return goodsDao.searchGoodsList(name,describe);
    }

    /**
     * 获取用户发布的商品
     *
     * @param userId 用户的id
     * @return List<GoodsExtend>
     */
    @Override
    public List<GoodsExtend> getUserGoods(Integer userId) {
        return goodsDao.getGoodsByUserId(userId);
    }

    /**
     * 根据商品的id和用户的id，查询商品
     *
     * @param goodsId 商品id
     * @param userId  用户id
     * @return GoodsExtend
     */
    @Override
    public GoodsExtend getUserByUserIdAndGoodsId(Integer goodsId, Integer userId) {
        return goodsDao.getGoodsByGoodsIdAndUserId(goodsId,userId);
    }

    /**
     * 根据商品id , 获取商品
     *
     * @param id 商品id
     * @return Good
     */
    @Override
    public Good getGoodsByGoodsId(Integer id) {
        return goodsDao.getGoodsById(id);
    }

    /**
     * 根据商品id，修改商品信息
     *
     * @param goods 商品
     * @return true代表修改成功，否则失败
     */
    @Override
    public boolean updateGoods(Good goods) {
        return goodsDao.updateGoodsByGoodsId(goods) == 1;
    }

    /**
     * 删除下架的商品
     *
     * @param id 商品的id
     * @return true代表删除成功，否则失败
     */
    @Override
    public boolean deleteGoods(Integer id) {
        return goodsDao.deleteGoodsByGoodsId(id) == 1;
    }

    /**
     * 获取所有商品
     *
     * @return List<goods>集合
     */
    @Override
    public List<Good> getAll() {
        return goodsDao.getAll();
    }

    /**
     * 批量删除商品
     *
     * @param ids 商品id数组
     * @return true删除成功；false删除失败
     */
    @Override
    public boolean deleteGoodsBatch(Integer[] ids) {
        return goodsDao.deleteGoodsBatch(ids) >= 1;
    }

    /**
     * 获取商品的图片
     *
     * @param ids Integer[] ids
     * @return List<String>
     */
    @Override
    public List<String> getGoodsImages(Integer[] ids) {
        return goodsDao.getGoodsImages(ids);
    }

    /**
     * 查询所有符合条件（goods）的商品
     *
     * @param goods 条件
     * @return List<Good>
     */
    @Override
    public List<Good> getGoodsBySelect(Good goods) {
        return goodsDao.getGoodsBySelect(goods);
    }


    /**
     * 保存图片名称到数据库的image表
     *
     * @param goodsId 商品id
     * @param files   图片信息
     * @return 保存成功返回 Map<String, MultipartFile>，否则返回null
     */
    @Override
    public Map<String, MultipartFile> saveImagesToDb(MultipartFile[] files, int goodsId) {
        if (files.length <= 6) {
            // 保存图片数据，指定初始值为6
            Map<String, MultipartFile> fileMap = new HashMap<String, MultipartFile>(6);
            // 图片旧名称
            String oldFileName = null;
            // 判断文件是否符合要求
            for (MultipartFile file : files) {
                // 如果文件不为空，且是图片文件
                if (!file.isEmpty() && Objects.requireNonNull(file.getContentType()).contains("image/")) {
                    // 获取文件名称
                    oldFileName = file.getOriginalFilename();
                    // 如果文件名称存在
                    if (oldFileName != null && oldFileName.length() > 0) {
                        // 设置文件的新名称
                        String fileName = UuidUtil.getUuid() + oldFileName.substring(oldFileName.lastIndexOf("."));
                        // image表 插入数据
                        imageDao.insert(goodsId, fileName);
                        // 保存图片数据到集合
                        fileMap.put(fileName, file);
                    } else {
                        // 只要有一个文件不合法，返回null
                        return null;
                    }
                } else {
                    // 只要有一个文件不合法，返回null
                    return null;
                }
            }
            // 文件保存成功
            return fileMap;
        }
        // 上传的文件为空，返回null
        return null;
    }


    /**
     * 保存商品的所有信息到数据库，保存图片到磁盘，对应商品类型数量增加
     *
     * @param files MultipartFile[]
     * @param goods 商品信息对象
     * @return true代表保存成功；否则保存失败
     */
    @Override
    public boolean saveGoodsMsg(Good goods, MultipartFile[] files, HttpServletRequest request) {
        // 查询当前对象
        User activeUser = (User) request.getSession().getAttribute("activeUser");
        // 设置goods 的id
        goods.setUser_id(activeUser.getId());
        // 设置发布时间
        goods.setStart_time(DateUtil.getNowDay());
        // 设置擦亮时间
        goods.setPublish_time(DateUtil.getNowTime());
        // 设置状态
        goods.setStatus((byte) 1);
        // 插入数据库，返回插入的商品的id给goods
        goodsDao.insert(goods);
        // 增加对应商品类型数量
        catelogDao.addNumberById(goods.getCatelog_id());
        // 保存商品图片
        Map<String, MultipartFile> fileMap = this.saveImagesToDb(files, goods.getId());
        // 如果商品数据保存到数据库成功，则再保存图片到磁盘
        if (fileMap != null) {
            this.saveImagesToDisk(fileMap);
            return true;
        } else {
            return false;
        }
    }
}
